﻿using FlyingEye.Application.Exceptions;
using FlyingEye.Application.NetServices;
using HslCommunication.Profinet.Melsec;
using HslCommunication.Profinet.Omron;

namespace FlyingEye.NetServices
{
    internal class MelsecMcNetDevice : IDevice
    {
        public string IP { get; }

        public int Port { get; }

        public string DeviceName { get; }

        private readonly MelsecMcNet _melsecMcNet;

        private bool _isConnected;

        public MelsecMcNetDevice(string deviceName, string ip, int port)
        {
            DeviceName = deviceName;
            IP = ip;
            Port = port;
            _melsecMcNet = new MelsecMcNet(ip, port);
        }

        public void Close()
        {
            if (_isConnected)
            {
                _melsecMcNet.ConnectClose();
            }
        }

        public void Connect()
        {
            _melsecMcNet.ConnectTimeOut = 1000; // 连接超时设置为 1s
            var result = _melsecMcNet.ConnectServer();
            _isConnected = result.IsSuccess;

            if (!result.IsSuccess)
            {
                throw new DeviceConnectException(result.ErrorCode);
            }
        }

        public bool ReadBool(string addr)
        {
            var result = _melsecMcNet.ReadBool(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public byte ReadByte(string addr)
        {
            var result = _melsecMcNet.Read(addr, 1);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content.First();
        }

        public double ReadDouble(string addr)
        {
            var result = _melsecMcNet.ReadDouble(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public float ReadFloat(string addr)
        {
            var result = _melsecMcNet.ReadFloat(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public int ReadInt(string addr)
        {
            var result = _melsecMcNet.ReadInt32(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public short ReadShort(string addr)
        {
            var result = _melsecMcNet.ReadInt16(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public string ReadString(string addr, ushort length)
        {
            var result = _melsecMcNet.ReadString(addr, length);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public uint ReadUint(string addr)
        {
            var result = _melsecMcNet.ReadUInt32(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public ushort ReadUshort(string addr)
        {
            var result = _melsecMcNet.ReadUInt16(addr);

            if (!result.IsSuccess)
            {
                throw new DeviceReadException(result.ErrorCode, result.Message);
            }
            return result.Content;
        }

        public void WriteBool(string addr, bool value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteByte(string addr, byte value)
        {
            var result = _melsecMcNet.Write(addr, new byte[] { value });

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteDouble(string addr, double value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteFloat(string addr, float value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteInt(string addr, int value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteShort(string addr, short value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteString(string addr, string value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteUint(string addr, uint value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }

        public void WriteUshort(string addr, ushort value)
        {
            var result = _melsecMcNet.Write(addr, value);

            if (!result.IsSuccess)
            {
                throw new DeviceWriteException(result.ErrorCode, result.Message);
            }
        }
    }
}
